<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <title>翻翻棋游戏</title>
  <style>
    :root{
      --bg-start:#f6f9fc;
      --bg-end:#e9f1fb;
      --card:#ffffff;--accent:#2b8aee;--muted:#6b7280;
    }
    *{box-sizing:border-box}
    body{
      font-family:system-ui,-apple-system,Segoe UI,Roboto,'Helvetica Neue',Arial;
      margin:0;
      /* use CSS variables for gradient so we can change theme by toggling classes */
      background:linear-gradient(180deg,var(--bg-start),var(--bg-end));
      transition:background 300ms ease;
      min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px
    }
    /* theme classes */
    .bg-a{ --bg-start:#ffe5e5; --bg-end:#ffdede; }
    .bg-b{ --bg-start:#e5f0ff; --bg-end:#dceeff; }

    .wrap{width:100%;max-width:980px;background:var(--card);border-radius:12px;box-shadow:0 8px 30px rgba(43,138,238,0.12);padding:20px;display:none}
    header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;flex-wrap:wrap;gap:10px}
    h1{font-size:18px;margin:0}
    .controls{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
    button{background:var(--accent);color:#fff;border:0;padding:8px 12px;border-radius:8px;cursor:pointer;font-weight:600}
    button.secondary{background:#fff;color:var(--accent);border:1px solid rgba(43,138,238,0.18)}
    select{padding:6px 8px;border-radius:6px;border:1px solid rgba(43,138,238,0.3)}
    .info{display:flex;gap:16px;align-items:center;justify-content:space-between;flex-wrap:wrap}
    .players{display:flex;gap:8px;align-items:center}
    .player{padding:8px 10px;border-radius:8px;background:#f3f7ff;border:1px solid rgba(43,138,238,0.06)}
    .player.active{box-shadow:0 4px 12px rgba(43,138,238,0.12);border-color:var(--accent);}
    .board{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;padding:12px;background:linear-gradient(180deg,#fff,#f7fbff);border-radius:10px}
    .card{aspect-ratio:1/1;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:50px;background:linear-gradient(180deg,#fafafa,#f0f6ff);cursor:pointer;user-select:none;position:relative;border:1px solid rgba(0,0,0,0.06)}
    .card.face-down{background:linear-gradient(180deg,#2b8aee,#2066b6);color:transparent}
    .card.matched{opacity:0.45;transform:scale(0.98)}
    .footer{margin-top:12px;color:var(--muted);font-size:13px}
    .menu{background:var(--card);padding:40px;border-radius:12px;box-shadow:0 8px 30px rgba(43,138,238,0.12);text-align:center;max-width:420px}
    .menu h1{margin-bottom:20px}
    .menu select{margin-bottom:20px}
  </style>
</head>
<body>
  <div class="menu" id="menu">
    <h1>翻翻棋游戏 — 记忆对对碰</h1>
    <p>选择难度：</p>
    <select id="menuDifficulty">
      <option value="easy">简单 (3x4)</option>
      <option value="medium">中等 (4x5)</option>
      <option value="hard">困难 (5x6)</option>
    </select>
    <p><button id="startBtn">开始游戏</button></p>
    <p><button id="howBtn" class="secondary">游戏说明</button></p>
  </div>

  <div class="wrap" id="gameWrap">
    <header>
      <h1>翻翻棋游戏 — 记忆对对碰</h1>
      <div class="controls">
        <div class="countdown">倒计时：<span id="count">10</span>s</div>
        <button id="restart">重新开始</button>
        <button id="backMenu" class="secondary">返回菜单</button>
      </div>
    </header>

    <div class="info">
      <div class="players">
        <div id="playerA" class="player active">姝妤：<span id="scoreA">0</span></div>
        <div id="playerB" class="player">泰宇：<span id="scoreB">0</span></div>
      </div>
      <div class="status">
        <div class="big">当前轮：<span id="current">姝妤</span></div>
        <div>已配对：<span id="matched">0</span>/<span id="totalPairs">0</span></div>
      </div>
    </div>

    <main style="margin-top:12px">
      <div id="board" class="board"></div>
    </main>

    <div class="footer">规则：所有牌开始正面朝上，10秒倒计时后全部翻至背面。玩家每次翻两张，配对则归当前玩家并继续，配对失败则换对方。棋盘清空时得分多者胜出。</div>
  </div>

<script>
(function(){
  const allEmojis = ['🍎','🍊','🍌','🍉','🍇','🍓','🍒','🍍','🥭','🥝','🍑','🍐','🥥','🍋','🍈'];
  let deck = [], first=null, second=null, lock=false;
  let currentPlayer='A', scoreA=0, scoreB=0, matchedPairs=0, totalPairs=0;
  const board=document.getElementById('board');
  const countEl=document.getElementById('count');
  const restartBtn=document.getElementById('restart');
  const currentEl=document.getElementById('current');
  const scoreAEl=document.getElementById('scoreA');
  const scoreBEl=document.getElementById('scoreB');
  const matchedEl=document.getElementById('matched');
  const totalPairsEl=document.getElementById('totalPairs');
  const playerAEl=document.getElementById('playerA');
  const playerBEl=document.getElementById('playerB');
  const gameWrap=document.getElementById('gameWrap');
  const menu=document.getElementById('menu');
  const startBtn=document.getElementById('startBtn');
  const menuDiff=document.getElementById('menuDifficulty');
  const backMenu=document.getElementById('backMenu');

  // audio disabled for ipad compatibility
  // const bgm=new Audio('sounds/bgm.mp3'); bgm.loop=true;
  // const flipSound=new Audio('sounds/flip.mp3');
  // const matchSound=new Audio('sounds/match.mp3');

  const bodyEl = document.body; // for theme toggling

  function buildDeck(){
    let rows=4, cols=5;
    if(menuDiff.value==='easy'){rows=3;cols=4;}
    else if(menuDiff.value==='hard'){rows=5;cols=6;}
    const pairs=(rows*cols)/2;
    totalPairs=pairs;
    totalPairsEl.innerText=pairs;
    board.style.gridTemplateColumns=`repeat(${cols},1fr)`;

    deck=[];
    const pool = allEmojis.slice(0,pairs);
    pool.forEach(e=>{deck.push({emoji:e}),deck.push({emoji:e})});
    for(let i=deck.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[deck[i],deck[j]]=[deck[j],deck[i]];}
  }

  function renderBoard(){
    board.innerHTML='';
    deck.forEach((card,index)=>{
      const el=document.createElement('div');
      el.className='card face-up';
      el.dataset.index=index;
      el.dataset.matched='0';
      el.textContent=card.emoji; // show emoji when face-up
      el.addEventListener('click',onCardClick);
      board.appendChild(el);
      card.el=el;
    });
  }

  function flipDown(el){
    el.classList.remove('face-up');
    el.classList.add('face-down');
    // clear content to avoid some WebKit-based browsers (Edge on iPad) keeping emoji visible
    el.textContent = '';
  }
  function flipUp(el){
    el.classList.remove('face-down');
    el.classList.add('face-up');
    // restore emoji from deck based on index
    const idx = +el.dataset.index;
    el.textContent = deck[idx].emoji;
  }

  function onCardClick(e){
    if(lock) return;
    const el = e.currentTarget;
    const idx = +el.dataset.index;
    if(el.dataset.matched === '1') return;
    if(el.classList.contains('face-down')){
      // flipSound.play(); (audio disabled)
      flipUp(el);
      if(!first){ first = {idx,el}; }
      else if(!second && idx !== first.idx){ second = {idx,el}; lock = true; checkMatch(); }
    }
  }

  function checkMatch(){
    const a = deck[first.idx];
    const b = deck[second.idx];
    if(a.emoji === b.emoji){
      // matchSound.play();
      a.matched = b.matched = true;
      first.el.dataset.matched='1';
      second.el.dataset.matched='1';
      first.el.classList.add('matched');
      second.el.classList.add('matched');
      if(currentPlayer === 'A'){ scoreA++; scoreAEl.innerText = scoreA; }
      else { scoreB++; scoreBEl.innerText = scoreB; }
      matchedPairs++;
      matchedEl.innerText = matchedPairs;
      first = null; second = null; lock = false;
      if(matchedPairs === totalPairs) endGame();
    } else {
      setTimeout(()=>{
        flipDown(first.el);
        flipDown(second.el);
        first = null; second = null; lock = false; switchPlayer();
      },800);
    }
  }

  function switchPlayer(){
    currentPlayer = currentPlayer === 'A' ? 'B' : 'A';
    currentEl.innerText = currentPlayer === 'A' ? '姝妤' : '泰宇';
    playerAEl.classList.toggle('active', currentPlayer === 'A');
    playerBEl.classList.toggle('active', currentPlayer === 'B');
    updateBackgroundColor();
  }

  function updateBackgroundColor(){
    if(currentPlayer === 'A'){
      bodyEl.classList.add('bg-a');
      bodyEl.classList.remove('bg-b');
    } else {
      bodyEl.classList.add('bg-b');
      bodyEl.classList.remove('bg-a');
    }
  }

  function endGame(){
    lock = true;
    // bgm.pause();
    let message = '';
    if(scoreA > scoreB) message = `姝妤 胜利！得分 ${scoreA}:${scoreB}`;
    else if(scoreB > scoreA) message = `泰宇 胜利！得分 ${scoreB}:${scoreA}`;
    else message = `平局！双方得分 ${scoreA}:${scoreB}`;
    setTimeout(()=>{ alert(message); showMenu(); }, 300);
  }

  function startCountdown(seconds=10){
    let t = seconds;
    countEl.innerText = t;
    board.querySelectorAll('.card').forEach(c=>{ c.classList.remove('face-down'); c.classList.add('face-up'); c.dataset.matched='0'; c.classList.remove('matched'); const idx=+c.dataset.index; c.textContent = deck[idx].emoji; });
    const iv = setInterval(()=>{ t--; countEl.innerText = t; if(t<=0){ clearInterval(iv); board.querySelectorAll('.card').forEach(c=>flipDown(c)); setTimeout(()=>{ lock=false; },150); } },1000);
  }

  function resetGame(){
    first=null; second=null; lock=true;
    currentPlayer='A'; scoreA=0; scoreB=0; matchedPairs=0;
    currentEl.innerText = '姝妤'; scoreAEl.innerText='0'; scoreBEl.innerText='0'; matchedEl.innerText='0';
    playerAEl.classList.add('active'); playerBEl.classList.remove('active');
    buildDeck(); renderBoard(); updateBackgroundColor(); startCountdown(10);
    // bgm.currentTime=0; bgm.play();
  }

  function showMenu(){
    // bgm.pause();
    menu.style.display='block';
    gameWrap.style.display='none';
    bodyEl.classList.remove('bg-a','bg-b');
  }

  function startGame(){
    menu.style.display='none';
    gameWrap.style.display='block';
    resetGame();
  }

  startBtn.addEventListener('click',()=>startGame());
  backMenu.addEventListener('click',()=>showMenu());
  restartBtn.addEventListener('click',()=>{ if(confirm('确认要重新开始游戏吗？')) resetGame(); });

  // show menu initially
  showMenu();
})();
</script>
</body>
</html>
